<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Electromagnetic Field Diagram</title>
</head>
<body>
<canvas id="physicsCanvas" width="500" height="520"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style and Configuration ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    const baseFont = 'Arial';
    const chineseFont = '"SimSun", "Songti SC"';

    // --- Helper Function ---
    function drawArrow(fromX, fromY, toX, toY, headLength = 10) {
        const dx = toX - fromX;
        const dy = toY - fromY;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(fromX, fromY);
        ctx.lineTo(toX, toY);
        ctx.moveTo(toX, toY);
        ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(toX, toY);
        ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }

    // --- Main Drawing Logic ---

    // 1. Define Geometry
    const O = { x: 250, y: 370 };
    const axisLength = { z: 250, y: 200, x_proj: 150, y_proj: 75 };
    const h_canvas = 180;
    const loopCenter = { x: O.x, y: O.y - h_canvas };
    const r_major = 160; // Semi-major axis (along y)
    const r_minor = 55;  // Semi-minor axis (perspective foreshortening)

    // 2. Draw Coordinate System
    ctx.lineWidth = 1.5;
    ctx.font = `italic 22px ${baseFont}`;
    // Z-axis
    drawArrow(O.x, O.y, O.x, O.y - axisLength.z);
    ctx.fillText('z', O.x - 20, O.y - axisLength.z - 5);
    // Y-axis
    drawArrow(O.x, O.y, O.x + axisLength.y, O.y);
    ctx.fillText('y', O.x + axisLength.y + 15, O.y);
    // X-axis
    const xEndPoint = { x: O.x - axisLength.x_proj, y: O.y + axisLength.y_proj };
    drawArrow(O.x, O.y, xEndPoint.x, xEndPoint.y);
    ctx.fillText('x', xEndPoint.x - 20, xEndPoint.y + 5);
    // Origin label
    ctx.font = `22px ${baseFont}`;
    ctx.fillText('O', O.x - 20, O.y + 15);

    // 3. Draw the Loop (Ellipse)
    ctx.lineWidth = 2.5;
    ctx.beginPath();
    ctx.ellipse(loopCenter.x, loopCenter.y, r_major, r_minor, 0, 0, 2 * Math.PI);
    ctx.stroke();

    // 4. Draw Dashed Diameters
    ctx.save();
    ctx.lineWidth = 1.5;
    ctx.setLineDash([5, 5]);

    // Q1-Q2 diameter (along y-direction)
    ctx.beginPath();
    ctx.moveTo(loopCenter.x - r_major, loopCenter.y);
    ctx.lineTo(loopCenter.x + r_major, loopCenter.y);
    ctx.stroke();

    // P1-P2 diameter (along x-direction, perspective)
    const m_proj = -axisLength.y_proj / axisLength.x_proj;
    const p_dx_intersect = 1 / Math.sqrt(1 / r_major**2 + m_proj**2 / r_minor**2);
    const p_dy_intersect = m_proj * p_dx_intersect;
    const P1 = { x: loopCenter.x - p_dx_intersect, y: loopCenter.y - p_dy_intersect };
    const P2 = { x: loopCenter.x + p_dx_intersect, y: loopCenter.y + p_dy_intersect };
    ctx.beginPath();
    ctx.moveTo(P1.x, P1.y);
    ctx.lineTo(P2.x, P2.y);
    ctx.stroke();

    ctx.restore(); // Restore solid lines

    // 5. Draw Labels on and around the loop
    ctx.font = `24px ${baseFont}`;
    // P1, P2, Q1, Q2
    const drawSubscript = (char, sub, x, y) => {
        ctx.font = `24px ${baseFont}`;
        ctx.fillText(char, x, y);
        ctx.font = `16px ${baseFont}`;
        ctx.fillText(sub, x + 12, y + 8);
    };
    drawSubscript('Q', '1', loopCenter.x - r_major - 30, loopCenter.y);
    drawSubscript('Q', '2', loopCenter.x + r_major + 15, loopCenter.y);
    drawSubscript('P', '1', P1.x - 30, P1.y + 5);
    drawSubscript('P', '2', P2.x + 15, P2.y - 15);

    // r, m
    ctx.font = `italic 24px ${baseFont}`;
    const r_label_pos = { x: (loopCenter.x + P1.x) / 2, y: (loopCenter.y + P1.y) / 2 };
    ctx.fillText('r', r_label_pos.x - 15, r_label_pos.y + 5);
    ctx.fillText('m', P2.x + 5, P2.y - 40);

    // 6. Draw Current (I) Arrows and Labels
    ctx.lineWidth = 2;
    // Arrow on the left (near Q1)
    let angle1_start = 1.2 * Math.PI;
    let angle1_end = 0.8 * Math.PI;
    ctx.beginPath();
    ctx.ellipse(loopCenter.x, loopCenter.y, r_major, r_minor, 0, angle1_start, angle1_end, true);
    let head_x = loopCenter.x + r_major * Math.cos(angle1_end);
    let head_y = loopCenter.y + r_minor * Math.sin(angle1_end);
    let tangent_angle = Math.atan2(r_minor * Math.cos(angle1_end), -r_major * Math.sin(angle1_end));
    drawArrow(head_x, head_y, head_x, head_y, 10); // Draw arrowhead at the end of the arc
    ctx.stroke();
    
    // Arrow on the right (near Q2)
    let angle2_start = 0.2 * Math.PI;
    let angle2_end = -0.2 * Math.PI;
    ctx.beginPath();
    ctx.ellipse(loopCenter.x, loopCenter.y, r_major, r_minor, 0, angle2_start, angle2_end, true);
    head_x = loopCenter.x + r_major * Math.cos(angle2_end);
    head_y = loopCenter.y + r_minor * Math.sin(angle2_end);
    drawArrow(head_x, head_y, head_x, head_y, 10);
    ctx.stroke();

    // 'I' labels
    ctx.font = `italic 24px ${baseFont}`;
    ctx.fillText('I', loopCenter.x - 100, loopCenter.y - 50);
    ctx.fillText('I', loopCenter.x + 100, loopCenter.y + 50);

    // 7. Draw Height 'h' Indicator
    ctx.lineWidth = 1;
    const h_indicator_x = loopCenter.x + r_major + 40;
    const h_top_y = loopCenter.y;
    const h_bottom_y = O.y;
    ctx.beginPath();
    ctx.moveTo(h_indicator_x - 10, h_top_y); // Top T-bar
    ctx.lineTo(h_indicator_x + 10, h_top_y);
    ctx.moveTo(h_indicator_x, h_top_y);     // Vertical line
    ctx.lineTo(h_indicator_x, h_bottom_y);
    ctx.stroke();
    // Arrow head at the bottom
    drawArrow(h_indicator_x, h_bottom_y-1, h_indicator_x, h_bottom_y, 10);

    ctx.font = `italic 24px ${baseFont}`;
    ctx.fillText('h', h_indicator_x + 25, (h_top_y + h_bottom_y) / 2);

    // 8. Draw Text Labels (Plate and Caption)
    ctx.font = `24px ${chineseFont}`;
    ctx.fillText('超导平板', O.x, O.y + 40);
    ctx.fillText('电图 2.24.1', canvas.width / 2, 495);
</script>
</body>
</html>